﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Management;
using System.Configuration;

namespace PIS.TechGrid.Gadgets.ChangeIP
{
    public static class IPHelper
    {
        /// <summary>
        /// 获取当前IP配置
        /// </summary>
        /// <returns></returns>
        public static IPConfigList GetCurrentIPConfigs()
        {
            MyList<IPConfig> cfgs = new MyList<IPConfig>();

            ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled='TRUE'");
            ManagementObjectCollection querycollection = query.Get();
            foreach (ManagementObject mo in querycollection)
            {
                cfgs.Add(new IPConfig(mo));
            }

            IPConfigList ipCfgList = new IPConfigList(cfgs);

            return ipCfgList;
        }

        /// <summary>   
        /// 启用DHCP服务器   
        /// </summary>   
        public static void EnableDHCP()
        {
            ManagementClass wmi = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = wmi.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                //如果没有启用IP设置的网络设备则跳过   
                if (!(bool)mo["IPEnabled"])
                    continue;

                //重置DNS为空   
                mo.InvokeMethod("SetDNSServerSearchOrder", null);
                //开启DHCP   
                mo.InvokeMethod("EnableDHCP", null);
            }
        }

        /// <summary>
        /// 应用配置
        /// </summary>
        /// <param name="config"></param>
        public static void ApplyIPConfig(IPConfig config)
        {
            ManagementClass wmi = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = wmi.GetInstances();
            ManagementBaseObject inPar = null;
            ManagementBaseObject outPar = null;

            foreach (ManagementObject mo in moc)
            {
                //如果没有启用IP设置的网络设备则跳过
                if (!(bool)mo["IPEnabled"])
                    continue;

                if (mo["MACAddress"] != null && mo["MACAddress"].ToString() == config.MacAddress)
                {
                    //设置IP地址和掩码
                    if (config.IPAddresses.Count > 0 && config.IPSubnets.Count > 0)
                    {
                        inPar = mo.GetMethodParameters("EnableStatic");
                        inPar["IPAddress"] = config.IPAddresses.ToArray();
                        inPar["SubnetMask"] = config.IPSubnets.ToArray();
                        outPar = mo.InvokeMethod("EnableStatic", inPar, null);
                    }

                    //设置网关地址
                    if (config.IPGateways.Count > 0)
                    {
                        inPar = mo.GetMethodParameters("SetGateways");
                        inPar["DefaultIPGateway"] = config.IPGateways.ToArray();
                        outPar = mo.InvokeMethod("SetGateways", inPar, null);
                    }

                    //设置DNS地址
                    if (config.DNSServers.Count > 0)
                    {
                        inPar = mo.GetMethodParameters("SetDNSServerSearchOrder");
                        inPar["DNSServerSearchOrder"] = config.DNSServers.ToArray();
                        outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
                    }
                }
            }
        }

        private static string GetMOValue(ManagementObject mo, string key)
        {
            if (mo[key] == null)
            {
                return null;
            }
            else if (mo[key] is string[])
            {
                return (mo[key] as string[])[0];
            }
            else
            {
                return mo[key].ToString();
            }
        }

        public static T DeserializeFromXmlString<T>(string objstr)
        {
            using (StringReader sr = new StringReader(objstr))
            {
                XmlSerializer xz = new XmlSerializer(typeof(T));

                return (T)xz.Deserialize(sr);
            }
        }

        public static string SerializeToXmlString(object obj)
        {
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer xz = new XmlSerializer(obj.GetType());

                xz.Serialize(sw, obj);

                return sw.ToString();
            }
        }

        public static T DeserializeFromFile<T>(string filePath)
        {
            using (StreamReader sr = new StreamReader(filePath))
            {
                XmlSerializer xz = new XmlSerializer(typeof(T));

                return (T)xz.Deserialize(sr);
            }
        }

        public static void SerializeToFile(object obj, string filePath)
        {
            using (StreamWriter sw = new StreamWriter(filePath))
            {
                XmlSerializer xz = new XmlSerializer(obj.GetType());

                xz.Serialize(sw, obj);
            }
        }

        public static void SaveMyConfigList(MyIPConfigList myCfgList)
        {
            string cfgfile = ConfigurationSettings.AppSettings["ConfigFile"];

            SerializeToFile(myCfgList, cfgfile);
        }

        public static MyIPConfigList LoadMyConfigList()
        {
            string cfgfile = ConfigurationSettings.AppSettings["ConfigFile"];

            if (!File.Exists(cfgfile))
            {
                return null;
            }

            MyIPConfigList myCfgList = DeserializeFromFile<MyIPConfigList>(cfgfile);

            return myCfgList;
        }
    }
}
